package com.example.batch.core.reload;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import com.example.batch.core.properties.DataSourceProperties;
import com.example.batch.core.event.DataSourceReloadEvent;
import com.example.batch.core.exception.DataSourceReloadException;

@Component
@Slf4j
public class DataSourceReloadManager {

    private final DynamicRoutingDataSource dynamicDataSource;
    private final MultiDataSourceProperties properties;
    
    @Autowired
    private ApplicationEventPublisher eventPublisher;
    
    public synchronized void reloadDataSource(String name, DataSourceProperties newConfig) {
        try {
            // 创建新的数据源
            DataSource newDataSource = createDataSource(newConfig);
            
            // 验证新数据源
            validateDataSource(newDataSource);
            
            // 更新配置
            properties.getSources().put(name, newConfig);
            
            // 替换数据源
            Map<Object, Object> targetDataSources = new HashMap<>(
                dynamicDataSource.getResolvedDataSources());
            targetDataSources.put(name, newDataSource);
            dynamicDataSource.setTargetDataSources(targetDataSources);
            dynamicDataSource.afterPropertiesSet();
            
            // 发布事件
            eventPublisher.publishEvent(new DataSourceReloadEvent(name, newConfig));
            
            log.info("Successfully reloaded data source: {}", name);
        } catch (Exception e) {
            log.error("Failed to reload data source: " + name, e);
            throw new DataSourceReloadException("Failed to reload data source: " + name, e);
        }
    }
    
    private void validateDataSource(DataSource dataSource) throws SQLException {
        try (Connection conn = dataSource.getConnection()) {
            if (!conn.isValid(3000)) {
                throw new SQLException("Failed to validate new data source");
            }
        }
    }
} 